<?php

	//JACKED Manager functions
	
	require_once('jacked_sessions.php');
	
	//generateHash(string, string) -> string
	//found on the PHP Security Consortium page:
	////http://phpsec.org/articles/2005/password-hashing.html
	//takes a string and an optional second argument,
	////if $salt is not provided, the function will add an extra string of random
	////characters to the plaintext and return the SHA1 hash of the entire string,
	////and the original salt will be appended to the beginning of the hash.
	////if $salt is provided, see documentation
	function generateHash($plainText, $salt=NULL)
	{
		if ($salt === NULL){
			$salt = substr(md5(uniqid(rand(), true)), 0, JACKED_SALT_LENGTH);
		}else{
			$salt = substr($salt, 0, JACKED_SALT_LENGTH);
		}
		
		return $salt . sha1($salt . $plainText);
	}
	
	//Recursive array_key_exists, handles nested arrays or objects
	function array_key_exists_r($needle, $haystack)
	{
		$result = array_key_exists($needle, $haystack);
		if ($result)
			return $result;
		foreach ($haystack as $v)
		{
			if (is_array($v) || is_object($v))
				$result = array_key_exists_r($needle, $v);
			if ($result)
				return $result;
		}
		return $result;
	}
	
	//function to strip crap from comments
	function html2txt($document){
		$search = array('@<script[^>]*?>.*?</script>@si',  // Strip out javascript
 	       '@<[\/\!]*?[^<>]*?>@si',            // Strip out HTML tags
		   '@<style[^>]*?>.*?</style>@siU',    // Strip style tags properly
		   '@<![\s\S]*?--[ \t\n\r]*>@'        // Strip multi-line comments including CDATA
		);
		$text = preg_replace($search, '', $document);
		return $text;
	}
	
	//emulate strstr()'s before_needle arg in php v < 5.3
	//$h = haystack, $n = needle
	function strstrb($h, $n){
	    return array_shift(explode($n,$h,2));
	}
	
	/**
	 * Convert BR tags to nl
	 *
	 * @param string The string to convert
	 * @return string The converted string
	 */
	function br2nl($string)
	{
	    return preg_replace('/\<br(\s*)?\/?\>/i', "\n", $string);
	}
	
	//dumps a given var, if JACKED_DEBUG is not turned off
	function jacked_debug_dump($var){
		if(JACKED_DEBUG > 0){
			echo '<br /><font color="red">JACKED DEBUG VAR_DUMP:</font><br /><pre><code>';
			var_dump($var);
			echo '</code></pre><br />';
		}
	}
	
	//jackedLogin!!!! its for logging in.
	function jackedLogin($username, $password){
		$username = mysql_real_escape_string($username);
		$password = mysql_real_escape_string($password);
		$query = "SELECT password FROM " . JACKED_USERS_TABLE . " WHERE username='$username'";
		jacked_debug_dump($query);
		$result = mysql_query($query, JACKED_DEFAULT_LINK);
		$row = mysql_fetch_array($result);	
		if($row){
			$hash = $row['password'];
			$password = generateHash($password, $hash);
			$query = "SELECT id, admin FROM " . JACKED_USERS_TABLE . " WHERE username='$username' AND password='$password'";
			jacked_debug_dump($query);
			$result = mysql_query($query, JACKED_DEFAULT_LINK);
			$row = mysql_fetch_array($result);
			if($row){
				if(JACKED_LOGIN_SESSION_UNIQUE){
					$query = "SELECT id FROM sessions WHERE data LIKE '%userid|s:1:\"" . $row['id'] . "\"%'";
					jacked_debug_dump($query);
					$result = mysql_query($query, JACKED_DEFAULT_LINK);
					if(mysql_num_rows($result)){
						return array('done' => 'NOEP', 'reason' => 'This user is already logged in.');
					}
				}
				$admin = $row['admin'];	
				$userid = $row['id'];
				jackedSession_write("auth.post", array(
					'loggedIn' => true,
					'user'     => $username, 
					'userid'   => $userid,
					'adminLevel' => $admin,
					'sessionID' => md5($_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT'])
				));
				jacked_debug_dump($_SESSION);
				return true;
			}else{
				return array('done' => 'NOEP', 'reason' => 'Incorrect password');
			}
		}else{
			return array('done' => 'NOEP', 'reason' => 'That user does not exist');
		}
	}
	
	//checkLogin(void) -> boolean
	//checks logged in status, 
	////if logged in, returns true,
	////if not logged in, returns false
	function checkLogin(){
		return (jackedSession_read('auth.post.loggedIn') && (jackedSession_read('auth.post.sessionID') == md5($_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT'])));
	}
	
	//validateLogin(void) -> boolean
	//if user is logged in, calling script runs normally,
	////if user is not logged in, calling script is cancelled, 
	//////and login page is shown with error
	function validateLogin(){
		$answer = TRUE;
		if(!checkLogin()){
			$error = "You cannot view this page until you are logged in.";
			include_once('jacked_admin.php');
			$answer = FALSE;
		}
		return $answer;
	}
	
	
	//takes two timestamps and returns an array representation of the approximate time between them
	function timeBetween($then, $now){
		$diff = $now - $then;
		
		$years = (int)($diff / 31556926);
		$months = (int)(($diff - ($years * 31556926)) / 2629743);
		$days = (int)(($diff - ($years * 31556926) - ($months * 2629743)) / 86400);
		$hours = (int)(($diff - ($years * 31556926) - ($months * 2629743) - ($days * 86400)) / 3600);
		$mins = (int)(($diff - ($years * 31556926) - ($months * 2629743) - ($days * 86400) - ($hours * 3600)) / 60);
		$secs = (int)($diff - ($years * 31556926) - ($months * 2629743) - ($days * 86400) - ($hours * 3600) - ($mins * 60));
		
		$result[year] = $years;
		$result[month] = $months;
		$result[day] = $days;
		$result[hour] = $hours;
		$result[minute] = $mins;
		$result[second] = $secs;
		
		return $result;
	}
	
	//zipBackupJACKED(void) -> boolean
	//creates a zip file containing a complete backup of the 
	////site files at the current time in the /backups directory
	function zipBackupJACKED(){
		include_once('lib/zip.class.php');        // imports
		
		$name = "backups/" . date('YFjHis') . ".zip";
		$obj = new Archive_Zip($name); // name of zip file
		
		$file = getcwd();
		$dh  = opendir($file);
		while (false !== ($filename = readdir($dh))) {
			if(ereg('^jacked_.', $filename))
				$files[] = $filename;
		}
		
		if($obj->create($files)){
			$answer = TRUE;
		}else{
			$answer = FALSE;
		}
		
		return $answer;
	}
	
	
	////////////////
	//MySQL DB HAPS  //
         //////////////
	
	//SELECT val FROM table WHERE cond
	////default link can be overridden
	function jackedDBGetVal($val, $table, $cond = null, $link = JACKED_DEFAULT_LINK){
		if(stripos($val, "function:") === 0){
			$val = substr($val, 9); //function: ends at 9, lol.
			$query = "SELECT " . $val . " FROM `" . $table . "`";
		}else
			$query = "SELECT `" . $val . "` FROM `" . $table . "`";
		if($cond)
			$query .= " WHERE " . $cond;
		jacked_debug_dump($query);
		$result = mysql_query($query, $link);
		$row = mysql_fetch_array($result, MYSQL_NUM);
		
		if($result && mysql_num_rows($result) > 0)
			$final = stripslashes($row[0]);
		else
			$final = false;
		
		return $final;
	}
	
	//SELECT vals FROM table WHERE cond
	////default link can be overridden
	function jackedDBGetRowVals($vals, $table, $cond, $link = JACKED_DEFAULT_LINK, $result_type = MYSQL_BOTH){
		$query = "SELECT $vals FROM `" . $table . "` WHERE " . $cond;
		jacked_debug_dump($query);
		$result = mysql_query($query, $link);
		$row = mysql_fetch_array($result, $result_type);
		
		if($result && mysql_num_rows($result) > 0)
			$final = array_map("stripslashes", $row);
		else
			$final = false;
		
		return $final;
	}
	
	//SELECT * FROM table WHERE cond
	////default link can be overridden
	function jackedDBGetRow($table, $cond, $link = JACKED_DEFAULT_LINK, $result_type = MYSQL_BOTH){
		$query = "SELECT * FROM `" . $table . "` WHERE " . $cond;
		jacked_debug_dump($query);
		$result = mysql_query($query, $link);
		$row = mysql_fetch_array($result, $result_type);
		
		if($result && mysql_num_rows($result) > 0)
			$final = array_map("stripslashes", $row);
		else
			$final = false;
		
		return $final;
	}
	
	//SELECT * FROM table WHERE cond
	////default link can be overridden
	////returns the result
	function jackedDBGetResult($table, $cond, $link = JACKED_DEFAULT_LINK){
		$query = "SELECT * FROM `" . $table . "` WHERE " . $cond;
		jacked_debug_dump($query);
		$result = mysql_query($query, $link);
		
		if($result && mysql_num_rows($result) > 0)
			$final = $result;
		else
			$final = false;
		
		return $final;
	}
	
	//make does do a query!
	function jackedDBQuery($query, $link = JACKED_DEFAULT_LINK){
	    jacked_debug_dump($query);
	    $result = mysql_query($query, $link);
	    
		if($result && mysql_num_rows($result) > 0)
			$final = $result;
		else
			$final = false;
		
		return $final;
	}
	
	//INSERT INTO table (fields) VALUES (values)
	///$data is an associative array where $field=>$value
	////default link can be overridden
	////returns bool whether it worked
	function jackedDBInsertValues($table, $data, $link = JACKED_DEFAULT_LINK){
        $fields = array();
        $values = array();
	    foreach($data as $field => $value){
	        $fields[] = jackedDBSanitize($field, $link);
	        $values[] = jackedDBSanitize($value, $link);
	    }
		$query = "INSERT INTO $table (`" . implode($fields, '`, `') . "`) VALUES ('" . implode($values, '\', \'') . "')";
		jacked_debug_dump($query);
		$result = mysql_query($query, $link);
        $result = ($result)? mysql_insert_id($link) : $result;
		return $result;
	}
	
	//UPDATE table SET field1 = value1, ... fieldn = value1 WHERE cond
	///$data is an associative array where $field=>$value
	////default link can be overridden
	////returns bool whether it worked
	function jackedDBUpdate($table, $data, $cond, $link = JACKED_DEFAULT_LINK){
        $fields = array();
        $values = array();
		jacked_debug_dump($query);
	    foreach($data as $field => $value){
	        $pairs[] = "`" . jackedDBSanitize($field, $link) . "` = '" . jackedDBSanitize($value, $link) . "'";
	    }
	    
		$query = "UPDATE $table SET " . implode($pairs, '`, `') . " WHERE " . $cond;
		jacked_debug_dump($query);
		$result = mysql_query($query, $link);
		return $result;
	}
	
	//DELETE FROM table WHERE cond
	////default link can be overridden
	////returns bool whether it worked
	function jackedDBDelete($table, $cond, $link = JACKED_DEFAULT_LINK){
		$query = 'DELETE FROM ' . jackedDBSanitize($table) . ' WHERE ' . $cond;
		jacked_debug_dump($query);
		$result = mysql_query($query, $link);
		return $result;
	}
	
	//maybe handle some better mysql sanitizing later or something
	//takes a value, returns a sanitized version of it for mysql
	function jackedDBSanitize($value, $link = JACKED_DEFAULT_LINK){
	    return mysql_real_escape_string($value);
	}
	
	

	
	/////////////////////////////////
	//JACKED core functions, loaders and other shit   //
	                     ///////////////////////////////
	
	//set PHP constants in JS
	function jackedJSLoadConstants(){
		$consts = get_defined_constants(true);
		$consts = $consts[user];
		echo '<!--import JACKED constants from PHP--><script type="text/javascript">' . "\n";
		foreach($consts as $constant => $definition){
			if(substr($constant, 0, 7) == 'JACKED_'){
				echo 'var ' . $constant . ' = \'' . $definition . '\';' . "\n";
			}
		}
		echo '</script>' . "\n";
	}
	
	//set javascript variables passed from php
	////more later
	function jackedJSConnect($vars){
		echo '<!--import other variables from PHP--><script type="text/javascript">' . "\n";
		foreach($vars as $var){
			if(is_array($var['value'])){
				$value = json_encode($var['value']);
			}else if(is_string($var['value'])){
				$value = '\'' . $var['value'] . '\'';
			}else{
				$value = $var['value'];
			}
			echo 'var ' . $var['name'] . ' = ' . $value . ';' . "\n";
		}
		echo '</script>' . "\n";
	}
	
	//javascript template includes
	function jackedJSLoadTemplateIncludes($nav_parent, $nav_sub){
		$srcPath = '/scripts/template_includes/' . $nav_parent . '/' . ($nav_sub? $nav_sub . '/' : '');
		$mydir = JACKED_LOCAL_PATH . 'scripts/template_includes/' . $nav_parent . '/' . ($nav_sub? $nav_sub . '/' : '');
		if($nav_parent && $handle = opendir($mydir)){
			while(false !== ($file = readdir($handle))){
				if($file != '.' && $file != '..' && substr(strrev($file), 0, 3) == 'sj.'){
					echo '<script type="text/javascript" src="' . $srcPath . $file . '"></script>' . "\n";
				}
			}
		}
	}
	
	//javascript explicit packages loader
	function JACKED_load_javascript($packages){
	    if(!is_array($packages)){
        	$packages = explode(",", $packages);
	    }
	
    	foreach($packages as $js){
    	    //match registered packages
    		switch($js){
    			case "jacked_updater":
    				echo '<script type="text/javascript" src="/scripts/jacked_updater.js"></script>' . "\n";
    				break;
    			case "jacked_comics_uploader":
    				echo '<script type="text/javascript" src="/scripts/jacked_comics_uploader.js"></script>' . "\n";
    				break;
    			case "jacked_comics_editor":
    				echo '<script type="text/javascript" src="/scripts/jacked_comics_editor.js"></script>' . "\n";
    				break;
    			case "jacked_comics_queueManager":
    				echo '<script type="text/javascript" src="/scripts/jacked_comics_queueManager.js"></script>' . "\n";
    				break;
    			case "jacked_comics_manager":
    				echo '<script type="text/javascript" src="/scripts/jacked_comics_manager.js"></script>' . "\n";
    				break;
    			case "uploadify_core":
    				echo '<script type="text/javascript" src="/lib/uploadify/scripts/jquery.uploadify.v2.1.0.min.js"></script>' . "\n";
    				break;
    			case "uploadify_swfobject":
    				echo '<script type="text/javascript" src="/lib/uploadify/scripts/swfobject.js"></script>' . "\n";
    				break;
    			case "tumblr_json_feed":
    				echo '<script type="text/javascript" src="/scripts/tumblr_feed_handler.js"></script>' . "\n";
    				break;
				case "simplemodal":
					echo '<script type="text/javascript" src="/scripts/simplemodal/js/jquery.simplemodal.js"></script>' . "\n";
					echo '<script type="text/javascript" src="/scripts/simplemodal/js/osx.js"></script>' . "\n";
					echo '<link rel="stylesheet" media="screen" href="/scripts/simplemodal/css/osx.css" />' . "\n";
    			default:
    				break;
    		}
    	}
	
	}
?>